{T}

Nginx 架构基础

Nginx 采用 事件驱动异步非阻塞 的架构设计,使其在高并发场景下具有卓越的性能表现。整个架构可以概括为:一个 Master 进程 + 多个 Worker 进程 的主从结构,配合事件驱动模型和高度模块化的设计

code
┌─────────────────────────────────────────────────────────────┐
│                        客户端请求层                            │
│        (成千上万的并发连接请求)                                 │
└────────────────────────┬────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────┐
│                      Master 进程                             │
│  • 读取和验证配置文件                                          │
│  • 启动和管理 Worker 进程                                     │
│  • 监控 Worker 进程状态,异常时重启                             │
│  • 处理信号(重启、重载配置等)                                  │
│  • 绑定监听端口(由 Worker 继承)                               │
└────────────────────────┬────────────────────────────────────┘
                         │
         ┌───────────────┴───────────────┐
         │                               │
         ▼                               ▼
┌─────────────────┐           ┌─────────────────┐
│  Worker 进程 1  │    ...    │  Worker 进程 N    
│                 │           │                 │
│  • 接受连接      │           │  • 接受连接      │
│  • 读取请求      │           │  • 读取请求      │
│  • 处理业务      │           │  • 处理业务      │
│  • 响应客户端    │           │  • 响应客户端     │
└────────┬────────┘           └────────┬───────┘
         │                               │
         └───────────────┬───────────────┘
                         │
         ┌───────────────┴───────────────┐
         │                               │
         ▼                               ▼
┌─────────────────┐           ┌─────────────────┐
│   事件驱动引擎               │    模块系统        
│ (epoll/kqueue)  │           │                 │
│                 │           │  • 核心模块      │
│  • 监控 I/O 事件 │           │  • HTTP 模块     │
│  • 异步回调处理              │  • 事件模块       │
│  • 非阻塞 I/O    │           │  • 邮件模块      │
└─────────────────┘           └─────────────────┘

主从进程结构

Master 进程(主进程)

Master 进程是 Nginx 的"管理者",以 root 权限运行(通常),负责整个生命周期管理

职责说明
配置解析读取并解析 nginx.conf 配置文件,验证语法正确性
进程管理fork() 创建指定数量的 Worker 进程
进程监控监控 Worker 进程健康状态,异常退出时自动重启
信号处理接收和处理系统信号(HUP、TERM、QUIT 等)
端口绑定在启动时绑定监听端口,所有 Worker 继承这些已绑定的 socket
热部署支持平滑升级和配置重载,零停机时间

信号处理机制:

code
客户端 → 发送信号 → Master 进程 → 处理信号 → 影响 Worker 进程
信号命令作用
TERMnginx -s stop立即停止服务
QUITnginx -s quit优雅停止(处理完当前请求)
HUPnginx -s reload平滑重载配置文件
USR1nginx -s reopen重新打开日志文件(日志切割)
USR2-平滑升级可执行文件
WINCH-优雅关闭旧版本 Worker 进程

Worker 进程(工作进程)

Worker 进程是实际处理请求的"工作者",每个 Worker 进程都是单线程的,但能处理成千上万的并发连接。

核心特性:

c
// 伪代码:Worker 进程的主循环
void worker_process_cycle() {
    // 初始化事件驱动模型
    ngx_event_process_init();

    // 设置信号处理(忽略父进程关心的信号)
    sigprocmask(SIG_BLOCK, &set, NULL);

    // 进入无限循环
    for ( ;; ) {
        // 等待事件(非阻塞)
        process_events();

        // 处理定时器事件
        process_timer_events();
    }
}

进程特点:

特点说明优势
单线程每个 Worker 是单线程,避免线程锁竞争消除线程上下文切换开销
独立运行Worker 之间互不干扰,共享内存很少一个进程崩溃不影响其他进程
CPU 亲和可将 Worker 绑定到特定 CPU 核心减少 CPU 缓存失效,提升性能
并发连接单 Worker 可处理数万并发连接高效利用系统资源
无阻塞全异步非阻塞 I/O 模型不阻塞等待 I/O 操作

Worker 数量配置:

nginx
# 通常设置为 CPU 核心数
worker_processes auto;  # 自动检测 CPU 核心数

# 或者手动指定
worker_processes 4;     # 4 核 CPU 的推荐配置

# 每个 Worker 最大连接数
events {
    worker_connections 10240;  # 单 Worker 最大连接数
}

# 最大并发连接数 = worker_processes * worker_connections
# 示例:4 * 10240 = 40960 个并发连接

进程间通信 IPC

Worker 进程之间几乎不需要通信,主要通过共享内存进行有限的信息交换

共享内存用途:

用途模块说明
限流计数limit_conn / limit_req跨 Worker 共享连接/请求计数
负载均衡状态upstream共享后端服务器健康状态
缓存管理proxy_cache共享缓存元数据和键
会话保持sticky共享会话粘性信息
SSL 会话ssl_session_cache共享 SSL 会话缓存

进程间信号通信:

c
// Master 向 Worker 发送信号
ngx_signal_process(cycle, sig);

// Worker 收到信号后的处理
static void ngx_signal_handler(int signo) {
    switch (signo) {
        case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
            ngx_quit = 1;
            break;
        case ngx_signal_value(NGX_TERMINATE_SIGNAL):
            ngx_terminate = 1;
            break;
        case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
            ngx_reconfigure = 1;
            break;
    }
}

事件驱动模型

事件驱动是一种编程模型,程序不主动轮询检查状态,而是等待事件发生后再响应

图表渲染中…

I/O 多路复用技术

I/O 多路复用是 Nginx 事件驱动的核心技术,允许单个线程监控多个 I/O 描述符

多路复用机制对比:

机制支持平台连接数上限性能说明
select全平台1024 (受 FD_SETSIZE 限制)O(n)每次调用都线性遍历所有 fd
poll全平台无限制O(n)同 select,但无 fd 数量限制
epollLinux 2.6+无限制O(1)高效,只返回就绪的 fd
kqueueBSD/macOS无限制O(1)类似 epoll
/dev/pollSolaris无限制O(1)类似 epoll
IOCPWindows无限制异步真正的异步 I/O

epoll 工作原理

epoll 是 Linux 上最高效的 I/O 多路复用机制,是 Nginx 高性能的基石

epoll 三个核心函数:

c
// 1. 创建 epoll 实例
int epoll_create(int size);
// 返回 epollfd,size 参数在 Linux 2.6.8 后被忽略

// 2. 添加/修改/删除要监控的文件描述符
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
// op: EPOLL_CTL_ADD, EPOLL_CTL_MOD, EPOLL_CTL_DEL

// 3. 等待事件发生
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
// 返回就绪的事件数量,events 数组存储就绪事件

epoll 工作流程:

图表渲染中…

epoll 两种工作模式:

模式触发条件特点适用场景
LT (Level Triggered)状态发生变化默认模式,兼容性好普通应用
ET (Edge Triggered)状态变化瞬间高效,避免重复触发高性能场景

ET 模式优势:

c
// LT 模式(水平触发)
while (1) {
    n = epoll_wait(epfd, events, MAX_EVENTS, -1);
    for (i = 0; i < n; i++) {
        // 每次只读部分数据
        read(fd, buffer, 100);
        // 下次 epoll_wait 仍会触发,直到缓冲区空
    }
}

// ET 模式(边缘触发)
while (1) {
    n = epoll_wait(epfd, events, MAX_EVENTS, -1);
    for (i = 0; i < n; i++) {
        // 必须一次性读完所有数据
        while ((len = read(fd, buffer, sizeof(buffer))) > 0) {
            // 处理数据
        }
        // 设置非阻塞 I/O
        fcntl(fd, F_SETFL, O_NONBLOCK);
    }
}

Nginx 事件驱动实现

Nginx 对不同平台的 I/O 多路复用机制进行了抽象封装:

c
// Nginx 事件模块抽象
typedef struct {
    // 添加事件
    ngx_int_t (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);

    // 删除事件
    ngx_int_t (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);

    // 启用事件
    ngx_int_t (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);

    // 禁用事件
    ngx_int_t (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);

    // 添加连接
    ngx_int_t (*add_conn)(ngx_connection_t *c);

    // 删除连接
    ngx_int_t (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);

    // 处理事件(核心)
    ngx_int_t (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer,
                                 ngx_uint_t flags);

    // 初始化
    ngx_int_t (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);
} ngx_event_actions_t;

事件处理循环:

c
// Nginx Worker 事件处理主循环
void ngx_process_events_and_timers(ngx_cycle_t *cycle) {
    // 1. 尝试接受新连接(accept 锁)
    if (ngx_use_accept_mutex) {
        if (ngx_accept_disabled > 0) {
            // 连接数超限,暂时不 accept
            ngx_accept_disabled--;
        } else {
            // 获取 accept 锁
            if (ngx_trylock_accept_mutex(cycle) == NGX_OK) {
                // 添加 accept 事件
                ngx_rebuild_events_array(cycle);
            }
        }
    }

    // 2. 计算定时器超时时间
    timer = ngx_event_find_timer();

    // 3. 调用平台特定的事件等待函数(如 epoll_wait)
    delta = ngx_event_actions.process_events(cycle, timer, flags);

    // 4. 处理定时器事件
    ngx_event_process_posted(cycle, &ngx_posted_events);

    // 5. 处理 I/O 事件
    if (flags & NGX_POST_EVENTS) {
        ngx_event_process_posted(cycle, &ngx_posted_accept_events);
        ngx_event_process_posted(cycle, &ngx_posted_events);
    }
}

模块化设计

Nginx 采用高度模块化的设计,所有功能都通过模块实现。模块分为多个层次,耦合度极低。

code
┌─────────────────────────────────────────────────────────────┐
│                      模块层次结构                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              HTTP 过滤器模块 (Filter)                 │   │
│  │  • gzip 压缩  • 子替换  • SSI  • XSLT  • 图片处理   │   │
│  └─────────────────────────────────────────────────────┘   │
│                         ▼                                   │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              HTTP 处理模块 (Handler)                  │   │
│  │  • 静态文件  • 代理  • FastCGI  • uWSGI  • Memcache  │   │
│  └─────────────────────────────────────────────────────┘   │
│                         ▼                                   │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              HTTP 核心模块 (Core)                     │   │
│  │  • server/location  • root/alias  • listen          │   │
│  └─────────────────────────────────────────────────────┘   │
│                         ▼                                   │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              事件模块 (Event)                         │   │
│  │  • epoll  • kqueue  • /dev/poll  • select           │   │
│  └─────────────────────────────────────────────────────┘   │
│                         ▼                                   │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              核心模块 (Core)                         │   │
│  │  • 进程管理  • 配置解析  • 内存池  • 日志            │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

核心模块类型

核心模块(Core Module)

最基础的模块,提供 Nginx 运行所需的最基本功能

c
typedef struct {
    ngx_str_t             name;       // 模块名称
    void               *(*create_conf)(ngx_cycle_t *cycle);
    char               *(*init_conf)(ngx_cycle_t *cycle, void *conf);
    ngx_command_t        *commands;   // 指令数组
    ngx_uint_t           type;        // 模块类型
    ngx_int_t          (*init_module)(ngx_cycle_t *cycle);
    ngx_int_t          (*init_process)(ngx_cycle_t *cycle);
} ngx_core_module_t;
核心模块功能
ngx_core_module定义 worker_processes、error_log、pid 等全局指令
ngx_events_module定义事件驱动模型相关配置
ngx_errlog_module日志系统
ngx_openssl_moduleSSL/TLS 支持

事件模块(Event Module)

实现不同平台的事件驱动机制

c
typedef struct {
    ngx_str_t              *name;      // 事件模块名称
    void                 *(*create_conf)(ngx_cycle_t *cycle);
    char                 *(*init_conf)(ngx_cycle_t *cycle, void *conf);
    ngx_event_actions_t     actions;   // 事件操作函数指针
    ngx_int_t             (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);
    void                  (*done)(ngx_cycle_t *cycle);
} ngx_event_module_t;
事件模块支持平台说明
ngx_epoll_moduleLinux最常用,性能最优
ngx_kqueue_moduleBSD/macOSmacOS 默认选择
ngx_devpoll_moduleSolarisSolaris 平台
ngx_select_module通用兼容性好,性能较差
ngx_poll_module通用类似 select

HTTP 模块(HTTP Module)

实现 HTTP 协议相关功能,是 Nginx 最常用的模块类型

c
typedef struct {
    ngx_http_module_t       ctx;        // 上下文函数
    ngx_command_t          *commands;   // 配置指令
    ngx_uint_t              type;       // NGX_HTTP_MODULE
    ngx_int_t             (*init_master)(ngx_log_t *log);
    ngx_int_t             (*init_module)(ngx_cycle_t *cycle);
    ngx_int_t             (*init_process)(ngx_cycle_t *cycle);
    ngx_int_t             (*init_thread)(ngx_cycle_t *cycle);
    void                  (*exit_thread)(ngx_cycle_t *cycle);
    void                  (*exit_process)(ngx_cycle_t *cycle);
    void                  (*exit_master)(ngx_cycle_t *cycle);
} ngx_module_t;

标准 HTTP 模块分类:

分类模块功能
核心ngx_http_core_moduleserver、location、listen 等
代理ngx_http_proxy_module反向代理
负载均衡ngx_http_upstream_moduleupstream 定义和算法
FastCGIngx_http_fastcgi_modulePHP-FPM 代理
重写ngx_http_rewrite_moduleURL 重写和重定向
压缩ngx_http_gzip_moduleGzip 压缩
认证ngx_http_auth_basic_moduleHTTP 基本认证
限流ngx_http_limit_req_module请求速率限制
SSLngx_http_ssl_moduleHTTPS 支持

HTTP 过滤器模块(HTTP Filter Module)

对 HTTP 响应内容进行处理和转换

c
typedef struct {
    ngx_int_t (*preconfiguration)(ngx_conf_t *cf);
    ngx_int_t (*postconfiguration)(ngx_conf_t *cf);

    void *(*create_main_conf)(ngx_conf_t *cf);
    char *(*init_main_conf)(ngx_conf_t *cf, void *conf);

    void *(*create_srv_conf)(ngx_conf_t *cf);
    char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);

    void *(*create_loc_conf)(ngx_conf_t *cf);
    char *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);

    // 过滤器链
    ngx_http_output_header_filter_pt  output_header_filter;
    ngx_http_output_body_filter_pt    output_body_filter;
} ngx_http_module_t;
过滤器模块功能
ngx_http_copy_filter_module负责将数据发送到客户端(头部)
ngx_http_header_filter_module构造 HTTP 响应头
ngx_http_write_filter_module将数据写入 socket(尾部)
ngx_http_gzip_filter_moduleGzip 压缩响应体
ngx_http_ssi_filter_moduleSSI (Server Side Includes)
ngx_http_sub_filter_module响应内容替换
ngx_http_addition_filter_module响应追加内容
ngx_http_xslt_filter_moduleXSLT 转换
ngx_http_image_filter_module图片缩放、裁剪
ngx_http_chunked_filter_module分块传输编码

过滤器链工作流程:

图表渲染中…

模块加载机制

Nginx 的模块在编译时静态链接到二进制文件中

编译时模块选择:

bash
# 禁用模块
./configure --without-http_autoindex_module \
            --without-http_charset_module \
            --without-http_gzip_module

# 启用模块
./configure --with-http_ssl_module \
            --with-http_v2_module \
            --with-http_realip_module

# 添加第三方模块
./configure --add-module=/path/to/third-party-module

# 动态模块(Nginx 1.9.11+)
./configure --with-http_geoip_module=dynamic

模块初始化流程:

c
// Nginx 启动时按顺序调用各模块的初始化函数
ngx_int_t ngx_init_cycle(ngx_cycle_t *old_cycle) {
    // 1. 创建配置结构体
    for (i = 0; ngx_modules[i]; i++) {
        if (ngx_modules[i]->type != NGX_CORE_MODULE) {
            continue;
        }
        module = ngx_modules[i]->ctx;
        if (module->create_conf) {
            conf = module->create_conf(cycle);
        }
    }

    // 2. 解析配置文件
    ngx_conf_parse(&conf, &cycle->conf_file);

    // 3. 初始化模块
    for (i = 0; ngx_modules[i]; i++) {
        if (ngx_modules[i]->init_module) {
            if (ngx_modules[i]->init_module(cycle) != NGX_OK) {
                /* failed */
            }
        }
    }

    // 4. 创建 Worker 进程
    for (i = 0; i < last; i++) {
        ngx_spawn_process(cycle, ngx_worker_process_cycle,
                          (void *) (intptr_t) i, "worker process", type);
    }

    return NGX_OK;
}

Nginx 处理高并发连接

高并发处理原理

Nginx 能够处理高并发连接的关键在于:

  1. 单进程处理多连接:一个 Worker 进程可以同时处理成千上万的连接
  2. 非阻塞 I/O:I/O 操作不阻塞线程,可以处理其他连接
  3. 零拷贝技术:减少数据在内核空间和用户空间之间的复制
  4. 高效的内存管理:内存池减少分配开销

并发对比:

架构并发模型并发连接数内存占用CPU 开销
Apache (prefork)多进程数百高(进程切换)
Apache (worker)多线程数千中(线程切换)
Nginx单进程事件驱动数十万低(事件驱动)

零拷贝技术

Nginx 使用零拷贝技术提升文件传输性能

图表渲染中…
图表渲染中…

Nginx 配置:

nginx
# 启用 sendfile
sendfile on;

# 启用 tcp_nopush(一次性发送数据包)
tcp_nopush on;

# 启用 tcp_nodelay(禁用 Nagle 算法)
tcp_nodelay on;

性能对比:

场景传统方式sendfile性能提升
小文件2000 req/s5000 req/s2.5x
大文件500 MB/s3 GB/s6x
静态资源CPU: 80%CPU: 20%节省 60% CPU

accept 锁机制

多个 Worker 进程同时监听同一个端口时,需要使用 accept 锁来避免"惊群效应"

惊群效应: 当多个进程同时监听同一个 socket,有新连接到达时,所有进程都会被唤醒,但只有一个进程能 accept 到连接,其他进程被唤醒后继续休眠,造成资源浪费

accept 锁实现:

c
// 尝试获取 accept 锁
ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle) {
    // 如果 accept 被禁用,不竞争锁
    if (ngx_accept_disabled > 0) {
        return NGX_ERROR;
    }

    // 尝试获取锁
    if (ngx_shmtx_trylock(&ngx_accept_mutex)) {
        // 获取锁成功
        if (ngx_accept_mutex_held
            && ngx_accept_events == 0
            && !(ngx_event_flags & NGX_USE_RTSIG_EVENT))
        {
            // 已经持有锁且无新事件
            ngx_shmtx_unlock(&ngx_accept_mutex);
            return NGX_ERROR;
        }

        // 标记已持有锁
        ngx_accept_mutex_held = 1;

        // 添加或删除 accept 事件
        if (ngx_enable_accept_events(cycle) == NGX_ERROR) {
            ngx_shmtx_unlock(&ngx_accept_mutex);
            return NGX_ERROR;
        }

        return NGX_OK;
    }

    // 获取锁失败
    return NGX_ERROR;
}

accept 锁配置:

nginx
events {
    # 启用 accept 锁(默认)
    accept_mutex on;

    # 获取锁的最大等待时间
    accept_mutex_delay 500ms;

    # 每个 Worker 的最大连接数
    worker_connections 10240;
}

高并发性能调优

内核参数优化:

bash
# /etc/sysctl.conf

# 系统最大打开文件数
fs.file-max = 999999

# 单个进程最大打开文件数
fs.nr_open = 999999

# TCP 时间等待重用
net.ipv4.tcp_tw_reuse = 1

# TCP FIN 超时
net.ipv4.tcp_fin_timeout = 30

# TCP TIME_WAIT 最大数量
net.ipv4.tcp_max_tw_buckets = 6000

# 本地端口范围
net.ipv4.ip_local_port_range = 1024 65535

# TCP 接收缓冲区(最小/默认/最大)
net.ipv4.tcp_rmem = 4096 87380 16777216

# TCP 发送缓冲区(最小/默认/最大)
net.ipv4.tcp_wmem = 4096 65536 16777216

# SYN 队列最大长度
net.ipv4.tcp_max_syn_backlog = 8192

# 启用 SYN Cookies 防护
net.ipv4.tcp_syncookies = 1

# TCP keepalive 时间
net.ipv4.tcp_keepalive_time = 600

# 网络设备接收队列长度
net.core.netdev_max_backlog = 32768

# 默认接收缓冲区大小
net.core.rmem_default = 262144

# 默认发送缓冲区大小
net.core.wmem_default = 262144

# 最大接收缓冲区大小
net.core.rmem_max = 16777216

# 最大发送缓冲区大小
net.core.wmem_max = 16777216

Nginx 配置优化:

nginx
# 全局配置
user nginx;
worker_processes auto;  # 自动检测 CPU 核心数
worker_rlimit_nofile 65535;  # 每个进程的最大文件描述符

events {
    # 每个 Worker 的最大连接数
    worker_connections 10240;

    # 使用 epoll(Linux)
    use epoll;

    # accept 锁优化
    accept_mutex on;
    accept_mutex_delay 50ms;

    # 多个连接同时处理
    multi_accept on;
}

http {
    # 保持连接超时
    keepalive_timeout 65;
    keepalive_requests 10000;

    # sendfile 零拷贝
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    # 隐藏版本号
    server_tokens off;

    # 客户端请求体大小限制
    client_max_body_size 10m;
    client_body_buffer_size 128k;

    # 客户端头缓冲区大小
    client_header_buffer_size 4k;
    large_client_header_buffers 4 8k;

    # Gzip 压缩
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json application/javascript;

    # 缓冲区优化
    output_buffers 1 32k;
    postpone_output 1460;
}

性能测试:

bash
# 使用 wrk 进行压力测试
wrk -t12 -c400 -d30s http://your-domain.com/

# 使用 ab (Apache Bench)
ab -n 10000 -c 100 http://your-domain.com/

# 使用 siege
siege -c 100 -t 60S http://your-domain.com/

与传统 Web 服务器架构对比

架构对比表格

对比维度Apache PreforkApache WorkerApache EventNginx
进程模型多进程多进程+多线程多进程+事件多进程+单线程事件
并发处理每连接一进程每连接一线程单进程多连接单进程多连接
连接数上限~500~2000~10000~100000+
内存占用高(每进程~50MB)中(每线程~5MB)低(万连接~2.5MB)
CPU 开销高(进程切换)中(线程切换)极低(事件驱动)
静态文件性能一般较好极佳
动态语言支持PHP/CGI 原生PHP/CGI 原生PHP/CGI 原生需代理到后端
配置复杂度
稳定性极高